C128_FreeMemory_EDASS-128_FewSourceCodes By lived.ch, 15:18 10.05.2024 ------------------------------------------------------------------------------------------------------------- I needed a little distraction from coding. That's the result...! Everything is also on .d64 floppy {virtual} Making here some advertising for native Commodore C128 programming in assembler ;-) The below located source codes and files on .d64 will sure made you curios if you are looking to start with assembly coding on C128 computer! {my start was 2023, November! I am still pure and proud retro C128 assembly greenhorn} ------------------------------------------------------------------------------------------------------------- Important: This information is not meant for BASIC programming on C128! But only for programming with EDASS-128 on Commodore 128 *Native assembly programming directly on C128 is always a huge mystery due to leck of free memory for your own lines when assembly environment is installed. {*= With native, i mean real HW C128 or emulated C128. Ergo, no Cross-Compiler} Because i prefer native programming, even though people already in '70s,'80s used some kind of hardware cross-compiler to avoid leck of free memory on the host they were coding for, i made a decision to start {November 2023} and stay with it and accept all challenges and frustrations of nativer coding ;-) Last thing a heard was that people used ATARI ST {and many other computers} to code for Commodore C128 {I guess that was probably for Go64!}. They transferred the files using an interface and had no need to use the fancy 1571 drive, or any floppy drive at all. Several months ago I tried many assembly languages for C128 and eventually made a final choice to use EDASS-128. It is occupying a huge portion of free memory and you basically have following main free locations: Let us start! ----------------------------------------------------------------------------------------------------------------------- Well, first the OCCUPIED memory by EDASS-128: BANK 0 NOTE 0. $03e4 - $03ef Calling EDASS-128 1. $1a00 - $1bff ROM - Jump Tables* { see further below } 2. $f000 - $feff Routines in Common Area BANK 1 0. $b400 - $feff Main Program VECTORS 0. IMAIN - $0302 Modified by EDASS-128 1. CLTVEC- $0334 Do not touch or change! 2. SHFVEC- $0336 Do not touch or change! 3. ESCVEC- $0338 Do not touch or change! And we shouldn't forget the space needed for the source code, labels, comments etc. That is bringing us to what is available. ----------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------- AND NOW THE FREE MEMORY LOCATIONS WHICH CAN BE USED BY EDASS-128: $0B00 - $0bff If NO Datasette is used and also not SFK 2.1 Rev. A3 {However, you can use BASIC 7.0 version of SFK and this location will be free} $0c00 - $0dff If NO RS232 Interface is used and also not SFK 2.1 Rev. A3 { BASIC 7.0 version of SFK is making this location free } { you could go up to $fff, if you don't use SPRDEF for sprite definition } { that is a lot of room for practicing with assembler } { SPRDEF is storing sprite definitions from $0e00 to $0fff } { meaning, if you do plan using use sprites, you still have space $0c00 - 0dff } { from $1000 Function Keys are defined, so don't go there } { that's $0fff + $01 } $1300 - $19FF Huge Space below BASIC ($1C01), a bit less than 2KB... { note: between $1a00 and $1bff, EDASS-128 is resident } { don't 'poke' anything at that locations, UNLESS you'll use EDASS-128 ver. 2 } { Main location of EDASS-128 is $1b400 and up, Bank 1 } $1C00 - $3FFF BASIC RAM is AVAILABLE... { but as mentioned already, it's only 11 KB there without graphic screens } { However, if you aren't planning BASIC-Assembler cooperation } { then there you go, 11KB free space for your assembler code } Zero Page $00 - $ff Almost all is occupied by EDASS-128... { can't say what 'almost all' is, couldn't find any info } { But if only a few addresses are free, } { unused by the system, how much could 'almost all' be? } { UPDATE 08.05.2024: $fa, $fb, $fc, $fd are free for personal use in zero page area } { according to examples in EDASS-128 Book } If you aren't going to use SPRDEF, then there is: dec 4791-4853, hex $12B7-$12F5 free ,062 And that's still not all, there is more: ,{ bytes available } dec 0673, hex $02a1 Unused,001 vector, dec 0786-0787, hex $0312-$0313 Unused,002 dec 1021-1023, hex $03fd-$03ff Unused,003 dec 2024-2039, hex $07e8-$07f7 Unused,015 dec 2048-2559, hex $0800-$09FF Unused,512 { BASIC Runtime Stack (use if no BASIC is used) } dec 2622-2623, hex $0a3e-$0a3f Unused,002 dec 2651-2655, hex $0a5b-$0a5f Unused,005 dec 2670-2687, hex $0a6e-$0a7f Unused,018 dec 2736, hex $0ab0 Unused,001 dec 2746-2751, hex $0aba-$0abf Unused,006 dec 2757, hex $0ac5 Unused,001 dec 2758-2815, hex $0ac6-$0aff Unused,058 dec 4590-4607, hex $11ee-$11ff Unused,017 dec 4862-4863, hex $12FE-$12FF Unused,001 dec 16416 - 8, hex $4020-$ 2 Unused,003 dec 49200 - 2, hex $C030-$ 2 Unused,003 ----------------------------------------------------------------------------------------------------------------------- VERY IMPORTANT INFO: If you use GRAPHIC command, the BASIC start pointers are changed and BASIC area is moved to $4000. GRAPHIC color map {1KB} is starting at $1c00 to $1fff and GRAPHIC area itself is starting at $2000 until $3fff {8KB}. Now, with EDASS installed, you can't use space above $4000 because EDASS-128 is located there. That leaves you then only the free areas for your own code as listed above until $19ff. Why not until $1bff you might say! Well, between *$1a00 - 1bff also EDASS-128 is resident and that space of 512 bytes can't be used therefore. *However, EDASS-128 is coming in 2 versions and the 2nd one EDASS-128.2.0, can be executed as follows run "EDASS-128.2.0". This one gives you free space from $1300 to $1bff {additional 512 bytes}. In addition to above listed free locations, there are also some smaller, e.g. 1 - 6 bytes locations. Sounds small, but those are like pure GOLD! $02a1, $03fd-$03ff, $0a3e-$0a3f, $0a5b-$0a5f, $0ab0, $0aba-$0abf, $0ac5, $12FE-$12FF, $4020-$4022, $C030- $C032 And there is also another location which could be used in case you are not going to use SPRDEF, meaning Sprite Definition Editor. That is: $12B7-$12F5, exactly 62 bytes. Now, in EDASS-128, like also some other assembly language editors, you can define with asterisk {*} where your start address is going to be, e.g. *= $1300. But you can use this also to spread your code to the available free spaces in memory. ----------------------------------------------------------------------------------------------------------------------- EXAMPLE PROGRAMS in assembly using EDASS-128 {for C128} ----------------------------------------------------------------------------------------------------------------------- { EDASS-128 example 1 }: example1.asm -a:0011-a: -e: *= $1300 ;start address .obj m .bank 15 ; lda #$00 sta $d020 jsr $1400 ;go to $1400 ldx #$00 lda #$00 draw sta $2000,x ;draw 1/2 scr lin sta $20a0,x inx cpx #$a0 ;160 byte bne draw ldx #$00 lda #$05 ;green color sta $1c00,x ;give some color inx cpx #$28 bne color wait jsr $ffe4 cmp #$0d ;is enter pressed beq exit ;yes, exit. jmp wait exit lda #$00 ;leave gfx mode 1 sta $d8 rts ; *= $1400 ;move to $1400 ; lda #$20 ;set graphic sta $d8 ;mode 1 lda #$00 sta $ff00 jsr $6b30 rts ----------------------------------------------------------------------------------------------------------------------- { EDASS-128 example 2 }: This is one way to use it, but more practical way is to set load subroutines in one portions from where you can then load rest of your code into memory. example2.asm -a:0011-a: -e: *= $1300 ;start address .obj m .bank 15 ; jsr $77b3 ;fast mode lda #$93 ;clr screen jsr $ffd2 ; setbnk = $ff68 getcfg = $ff6b setlfs = $ffba setnam = $ffbd loadsp = $ffd5 start = $0e00 ;sprites ; sprflag lda #$00 cmp #$00 beq getspr bne sprdone getspr jsr loadspr sprdone jsr $77c4 ;slow again jmp $1500 ;main program ; *= $1400 ; loadspr ldx #$00 ;bank number jsr getcfg ;mmu-config jsr setbnk ;set bank lda #$01 ;logical file ldx #$08 ;device address ldy #$00 ;secondary addres jsr setlfs ;set config lda #$09 ;file lenght ldx #loads ;high-byte name jsr setnam ;set name lda #$00 ;load-verify ldx #start ;high-byte start jmp loadsp ;load & close loads .text "sprite.bl" ; *= $1500 ; lda #$01 sta sprflag+1 ;no more spr load sta $d020 ;border color sta $d015 ;sprite 1 sta $12fd ;bas irq off loop lda #$80 sta $d000 ;xy=128 sta $d001 ldx #$00 line lda #$e0 sta $0400+(12*40),x lda #$05 sta $d800+(12*40),x inx cpx #$28 bne line jsr $ffe4 cmp #$0d beq basic jmp loop basic rts ;basic ----------------------------------------------------------------------------------------------------------------------- { EDASS-128 example 3 }: If you want to load several files, best way to do it is to have an easy name and have noticed somewhere what exactly is loaded. E.g. .text '0max' Use then branch commands to load exactly what you need without a necessity to have xyz load routines, one for each file. 1max = load info screen -> $0400 > $05e0, dec 1024 > 1504, 12 lines 2max = load color map -> $d800 > $d9e0, dec 55296 > 55776, 12 lines 3max = load lived.ch -> $0608 > $07c0, dec 1544 > 1984, 12 lines {13 - 25, load from $05e0}, middle of the screen 4max = load color map -> $d800 > $d9e0, dec 55296 > 55776, 12 lines {13 - 25, load from $d9e0}, middle of the screen 5max = load sprites -> $0e00 > $0fff, dec 3584 > 4095, 12 lines {08 different sprites} 6max = load main code -> $1500 > ? How can you do that? {NOTE: first name is 1max, but it must start with 0max therefore} {Sure, we could have just jump over the first incrementing, but why would we wanna do that, right ;-)} This is loading 6 files with very little code. IMPORTANT INFO: Files {x}max were saved each individually by using BSAVE command in BASIC direct mode. You need to be familiar with the address. Not like a pro, but you should know by now that $0400 is the default screen start address and $d800 is start address of the 40 column color map are. Sprites are located at $0e00 until $0fff. {You could have them elsewhere too! All you need to do then is change the pointers in 2040-2047} {Default is 56 for 2040 = POKE 2040,56} To save full screen 40 column screen and color: bsave"screengfx",b15,p1024top1024+(25*40) bsave"screencol",b15,p55296top55296+(25*40) To save memory location you need, best is to use built-in Machine Language Monitor (ML) and see where your code ends. To save a location from $1300 to $13aa {where your loading routine is}: bsave"startme",b15,p4864top5034 To save your main code starting at $3000 - $3800 you type: bsave"main",b15,p12288top79872 Sprites are saved with following addresses. It's 512 bytes {8x 64 bytes = 512 bytes}. All 8 sprites! {but you can save them also individually}: bsave"mysprites",b15,p3584top3584+(512) And take a look at the example. example3.asm -a:0011-a: -e: *= $1300 ;start address .obj m .bank 15 ; lda #$00 sta $ff00 ; jsr $77b3 ;fast mode ; setbnk = $ff68 getcfg = $ff6b setlfs = $ffba setnam = $ffbd loadsp = $ffd5 start1 = $0400 ;load screen start2 = $d800 ;load color map start3 = $05e0 ;load lived.ch start4 = $d9e0 ;load colormap start5 = $0e00 ;load sprites start6 = $1500 ;load main prog ; jsr loadall ;l 1max info scrn jsr loadall ;l 2max color map jsr loadall ;l 3max lived.ch jsr loadall ;l 4max color map jsr loadall ;l 5max 8 sprites jsr loadall ;l 6max main code ; jsr $77c4 ;slow again ; lda #$00 ;resets sta max+1 ;for load correct lda #$30 ;next time sta loads ;#$30 = 0, ascii ; jmp $1500 ;main code ; loadall lda #$00 ;exclude sta $93 ;loading sta $9d ;searching inc max+1 inc loads ;increment name max lda #$00 ;counter ldx #$00 ;bank number jsr getcfg ;mmu-config jsr setbnk ;set bank lda #$01 ;logical file ldx #$08 ;device address ldy #$00 ;secondary addres jsr setlfs ;set config lda #$04 ;file lenght ldx #loads ;high-byte name jsr setnam ;set name ; lda max+1 ;read max value cmp #$01 beq getmax1 cmp #$02 beq getmax2 cmp #$03 beq getmax3 cmp #$04 beq getmax4 cmp #$05 beq getmax5 cmp #$06 beq getmax6 ; getmax1 lda #$00 ldx #start1 ;high-byte start jmp charge example3.asm -a:0083-a: -e: getmax2 lda #$00 ldx #start2 jmp charge getmax3 lda #$00 ldx #start3 jmp charge getmax4 lda #$00 ldx #start4 jmp charge getmax5 lda #$00 ldx #start5 jmp charge getmax6 lda #$00 ldx #start6 jmp charge ;not needed but.. charge jmp loadsp ;load / close loads .text "0max" ; *= $1500 ;always check if ; ;the address is ; ;correct! ; lda #$00 sta $d021 lda #$0e sta $d020 lda #$01 sta $12fd ;bas irq off lda #$c0 ;msb>255,spr 7,8 sta $d010 lda #$ff sta $d015 ;sprites on ldx #$00 readcol lda sprcol,x ;get spr colors sta $d027,x inx cpx #$08 bne readcol ; ldx #$00 ;set sprite pos setpos lda sprpos,x ;all 8 sta $d000,x inx cpx #$10 bne setpos ; loop jsr $ffe4 ;hit enter to cmp #$0d ;exit beq basic jmp loop basic rts ; ; ; sprcol .byte $01,$02,$03,$04 .byte $05,$06,$07,$08 ; ;sprites 1-8 xxx yyy position ; sprpos .byte $26,$e4 ;spr1 .byte $4c,$e4 ;spr2 .byte $72,$e4 ;.... .byte $98,$e4 .byte $be,$e4 .byte $e4,$e4 .byte $0b,$e4 ;> 255, $0b,msb .byte $31,$e4 ;> 255, $31,msb ----------------------------------------------------------------------------------------------------------------------- { EDASS-128 example 4 {REU01.ASM}: With 12000 bytes a good things can be achieved. That being said...hehe... I am thankful for the emulators we have nowadays. Because i can activate REU within 5 seconds and even choose which size i want. If it is already there, why not make some use out of it! TED 2.0 is screen based editor and it uses C128 BASIC editor to create tiles. Since most of the space i had free is gone i thought why not use REU to make screen backups {not saving, just temporary backup}. I had to peek online a little bit and found a solution here {THANKS!}: commodore128.mirkosoft.sk/reu.htmld {This is just a bit different from the original file, available at the address above, because i had to adapt it for my needs, and that is to have the screen transferred to REU. I'll probably end up with 10 screens, but who knows} - sys 4864 is writing screen {$0400 - $07e7} data to REU BANK 0, location #$00 - sys 5120 is reading REU data from BANK 0, location #$00 and writing to C128, $0400, which is standard VIC screen start area. reu01.asm -a:0011-a: -e: *= $1300 ;sys 4864 / write .obj m .bank 15 ; ;-------------------------------------- ;reu data transfer to save the default ;text screen area {commodore c128} ;screen data and screen color transfer ;-------------------------------------- ; ;thanks to: ;commodore128.mirkosoft.sk/reu.htmld ; ;i slightly modified this to have ;screen transfer of 1000 byte ; ; status = $df00 command = $df01 ;write=/read= c128s = $df02 ;source/target reubase = $df04 tsize = $df07 irqmack = $df09 control = $df0a ;------------------------------------ ; ;write from c128 memory to reu memory ; recreu lda #$00 sta control ; lda #$00 ;low screen sta c128s ; lda #$04 ;high screen sta c128s+1 ; ; lda #$00 ;low sta reubase lda #$00 ;high reu sta reubase+1 lda #$00 ;bank 2 sta reubase+2 ; lda #$00 ;trans size low sta tsize ; lda #$04 ;high sta tsize+1 ;screen 1000 byte lda #$90 sta command rts ; *= $1400 ;sys 5120 / read ; ;transfer from reu to c128 memory ; readreu lda #$00 sta control lda #$00 ;write to screen sta c128s lda #$04 sta c128s+1 ; lda #$00 ;take data sta reubase ;from $0000 lda #$00 ; sta reubase+1 lda #$00 ;in reu bank 2 sta reubase+2 ; lda #$00 ;transfer size sta tsize ;1000 bytes lda #$04 ;or one sta tsize+1 ;full lda #$91 ;screen sta command rts ----------------------------------------------------------------------------------------------------------------------- { EDASS-128 example 5 }: This copies all you do on screen, including every color, to REU {you must activate it in VICE} and then back by using following sys commands: sys 4864 > transfer from C128 to REU {screen and color map data} sys 5120 < transfer from REU to C128 {to screen $0400 and color map area $d800, 1000 bytes {each area}, hex $0400} example5.asm -e:0011-a: -e: *= $1300 ;sys 4864 / write .obj m .bank 15 ; ;-------------------------------------- ;reu data transfer to save the default ;text screen area {commodore c128} ;screen data and screen color transfer ;-------------------------------------- ; ;thanks to: ;commodore128.mirkosoft.sk/reu.htmld ; ;i slightly modified and corrected ;this to have data transfer of $0400 ;bytes and not $1000 bytes! because ;that is actually 4096 bytes. ;lived.ch, 11.05.2024 ; ; status = $df00 command = $df01 ;write=/read= c128 = $df02 ;source/target reubase = $df04 tsize = $df07 irqmack = $df09 control = $df0a screen = $0400 colmap = $d800 reuscr = $0000 ;reu screen reucol = $0400 ;reu color ;-------------------------------------- ; ;trans screen c128 > reu bank 0, $0000 ; recreu lda #$00 sta control lda #screen sta c128+1 lda #reuscr sta reubase+1 lda #$00 ;reu bank 0 sta reubase+2 lda #$00 ;transfer 1000 sta tsize ;bytes lda #$04 sta tsize+1 lda #$90 ;save to reu sta command ; rts ;-------------------------------------- ; ;trans colormap c128 > reu bank 0, $0400 ; lda #$00 sta control lda #colmap sta c128+1 lda #reucol sta reubase+1 lda #$00 ;reu bank 0 sta reubase+2 lda #$00 ;transfer 1000 sta tsize ;bytes lda #$04 sta tsize+1 lda #$90 ;save to reu sta command rts ; ; *= $1400 ;sys 5120 / read ; ; ;transfer from reu to c128 memory ; readreu lda #$00 sta control lda #screen sta c128+1 lda #reuscr ; sta reubase+1 lda #$00 ;in reu bank 2 sta reubase+2 ; lda #$00 ;transfer size sta tsize ;1000 bytes lda #$04 ; sta tsize+1 ; lda #$91 ;read & transfer sta command ; rts ; lda #$00 ;color reu > c128 sta control lda #colmap sta c128+1 lda #reucol sta reubase+1 lda #$00 ;in reu bank 2 sta reubase+2 ; lda #$00 ;transfer size sta tsize ;1000 bytes lda #$04 sta tsize+1 lda #$91 ;read & transfer sta command rts -----------------------------------------------------------------------------------------------------------------------